import express from 'express';
import cors from 'cors';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import * as fs from 'fs';
import * as path from 'path';

const app = express();
app.use(cors());
app.use(express.json());

// MCP Server实例
const server = new Server(
  {
    name: 'harmony-pilot-mcp',
    version: '1.0.0',
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

/**
 * 增强代码上下文
 */
async function enhanceContext(filePath: string, code: string): Promise<any> {
  console.log(`Enhancing context for: ${filePath}`);
  
  const enhanced = {
    filePath,
    codeLength: code.length,
    analysis: {
      hasOpenHarmonyImports: code.includes('OHOS::') || code.includes('ohos_'),
      isGNFile: filePath.endsWith('.gn'),
      isCppFile: filePath.endsWith('.cpp') || filePath.endsWith('.h'),
      hasTests: code.includes('TEST') || code.includes('EXPECT'),
    },
    suggestions: [] as string[],
  };
  
  // 添加建议
  if (enhanced.analysis.hasOpenHarmonyImports) {
    enhanced.suggestions.push('考虑添加OpenHarmony头文件保护');
    enhanced.suggestions.push('使用HiLog进行日志记录');
  }
  
  if (enhanced.analysis.isCppFile) {
    if (!code.includes('#pragma once') && !code.includes('#ifndef')) {
      enhanced.suggestions.push('添加头文件保护');
    }
  }
  
  return enhanced;
}

/**
 * 分析代码依赖
 */
async function analyzeDependencies(projectRoot: string, filePath: string): Promise<any> {
  console.log(`Analyzing dependencies for: ${filePath}`);
  
  const dependencies: string[] = [];
  const fullPath = path.join(projectRoot, filePath);
  
  try {
    if (fs.existsSync(fullPath)) {
      const content = fs.readFileSync(fullPath, 'utf-8');
      
      // 提取#include
      const includeRegex = /#include\s+[<"]([^>"]+)[>"]/g;
      let match;
      while ((match = includeRegex.exec(content)) !== null) {
        dependencies.push(match[1]);
      }
      
      // 提取GN依赖
      if (filePath.endsWith('.gn')) {
        const depsRegex = /deps\s*=\s*\[([\s\S]*?)\]/g;
        while ((match = depsRegex.exec(content)) !== null) {
          const depsContent = match[1];
          const depRegex = /"([^"]+)"/g;
          let depMatch;
          while ((depMatch = depRegex.exec(depsContent)) !== null) {
            dependencies.push(depMatch[1]);
          }
        }
      }
    }
  } catch (error) {
    console.error('Error analyzing dependencies:', error);
  }
  
  return {
    filePath,
    dependencies,
    count: dependencies.length,
  };
}

/**
 * 查询OpenHarmony API文档
 */
async function queryOHAPIDocs(apiName: string): Promise<any> {
  console.log(`Querying OH API docs for: ${apiName}`);
  
  // 这里可以集成实际的API文档数据库或爬虫
  const mockDocs: Record<string, any> = {
    'AbilityContext': {
      description: 'Ability上下文，提供Ability的运行环境信息',
      methods: ['startAbility', 'terminateSelf', 'connectServiceAbility'],
      example: 'this.context.startAbility(want);',
    },
    'HiLog': {
      description: 'OpenHarmony日志系统',
      methods: ['debug', 'info', 'warn', 'error', 'fatal'],
      example: 'HiLog::Info(LABEL, "message %{public}s", msg);',
    },
    'Want': {
      description: '意图对象，用于Ability之间的信息传递',
      properties: ['bundleName', 'abilityName', 'parameters'],
      example: 'Want want; want.SetBundleName("com.example.app");',
    },
  };
  
  return mockDocs[apiName] || {
    apiName,
    found: false,
    message: 'API文档未找到，建议查阅OpenHarmony官方文档',
  };
}

// 注册工具
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: 'enhance_context',
        description: '增强代码上下文信息，提供OpenHarmony特定的分析和建议',
        inputSchema: {
          type: 'object',
          properties: {
            filePath: {
              type: 'string',
              description: '文件路径',
            },
            code: {
              type: 'string',
              description: '代码内容',
            },
          },
          required: ['filePath', 'code'],
        },
      },
      {
        name: 'analyze_dependencies',
        description: '分析代码文件的依赖关系',
        inputSchema: {
          type: 'object',
          properties: {
            projectRoot: {
              type: 'string',
              description: '项目根目录',
            },
            filePath: {
              type: 'string',
              description: '文件路径',
            },
          },
          required: ['projectRoot', 'filePath'],
        },
      },
      {
        name: 'query_oh_api_docs',
        description: '查询OpenHarmony API文档',
        inputSchema: {
          type: 'object',
          properties: {
            apiName: {
              type: 'string',
              description: 'API名称',
            },
          },
          required: ['apiName'],
        },
      },
    ],
  };
});

// 处理工具调用
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;
  
  try {
    switch (name) {
      case 'enhance_context':
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(await enhanceContext(args.filePath, args.code), null, 2),
            },
          ],
        };
      
      case 'analyze_dependencies':
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(await analyzeDependencies(args.projectRoot, args.filePath), null, 2),
            },
          ],
        };
      
      case 'query_oh_api_docs':
        return {
          content: [
            {
              type: 'text',
              text: JSON.stringify(await queryOHAPIDocs(args.apiName), null, 2),
            },
          ],
        };
      
      default:
        throw new Error(`Unknown tool: ${name}`);
    }
  } catch (error: any) {
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify({ error: error.message }),
        },
      ],
      isError: true,
    };
  }
});

// HTTP端点（用于与Java服务通信）
app.post('/rpc', async (req, res) => {
  try {
    const { method, params } = req.body;
    
    if (method === 'tools/list') {
      const response = await server.request(
        { method: 'tools/list' },
        ListToolsRequestSchema
      );
      res.json(response);
    } else if (method === 'tools/call') {
      const response = await server.request(
        {
          method: 'tools/call',
          params: {
            name: params.name,
            arguments: params.arguments,
          },
        },
        CallToolRequestSchema
      );
      res.json(response);
    } else {
      res.status(400).json({ error: 'Unknown method' });
    }
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

app.get('/health', (req, res) => {
  res.json({ status: 'ok', service: 'MCP Server' });
});

const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
  console.log(`========================================`);
  console.log(`MCP Server started on port ${PORT}`);
  console.log(`Health check: http://localhost:${PORT}/health`);
  console.log(`========================================`);
});

// 也支持stdio传输（用于进程间通信）
async function runStdio() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error('MCP Server running on stdio');
}

// 如果有命令行参数--stdio，则使用stdio模式
if (process.argv.includes('--stdio')) {
  runStdio();
}

